<template>
  <!-- 树形表格容器 -->
  <div class="tree-table-container">
    <!-- 表格主体 -->
    <table class="tree-table">
      <!-- 表头 -->
      <thead>
        <tr>
          <th v-for="(col, index) in columns" :key="index" :style="{
            width: index === 0 ? '300rpx' : (col.width ? (typeof col.width === 'number' ? `${col.width}rpx` : col.width) : 'auto'),
            left: col.fixed === 'left' ? '0' : 'auto',
            zIndex: col.fixed ? 12 : 11
          }" :data-fixed="col.fixed">
            {{ col.title }}
          </th>
        </tr>
      </thead>
      <!-- 表格内容 -->
      <tbody>
        <!-- 循环渲染每一行数据 -->
        <tr v-for="item in flattenedData" :key="item.Fid" :class="{ 'has-children': item.children }">
          <!-- 动态渲染列 -->
          <td v-for="(col, colIndex) in columns" :key="colIndex" :style="{
            width: colIndex === 0 ? '300rpx' : (col.width ? (typeof col.width === 'number' ? `${col.width}rpx` : col.width) : 'auto'),
            paddingLeft: colIndex === 0 ? `${(item.level + 1) * 16}px` : '12px',
            position: col.fixed ? 'sticky' : 'static',
            left: col.fixed === 'left' ? '0' : 'auto',
            zIndex: col.fixed ? 1 : 'auto',
            background: col.fixed ? 'white' : 'inherit'
          }" :data-fixed="col.fixed">
            <!-- 第一列特殊处理 -->
            <template v-if="colIndex === 0">
              <!-- 展开/折叠图标 -->
              <span v-if="item.children" @click="() => toggleExpand(item.Fid)" class="expand-icon">
                {{ expandedItems.includes(item.Fid) ? '−' : '+' }}
              </span>
              <!-- 名称文本 -->
              <span class="name-text">{{ item[col.key] }}</span>
            </template>
            <template v-else>
              {{ item[col.key] }}
            </template>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, defineExpose, PropType, nextTick } from 'vue'

/**
 * 表格列定义接口
 * @property {string} title - 列标题
 * @property {string} key - 对应数据项的键名
 * @property {number|string} [width] - 列宽度，支持数字(rpx)或字符串格式
 * @property {'left'|'right'} [fixed] - 是否固定列及其位置
 */
interface Column {
  title: string
  key: string
  width?: number | string // 单位rpx
  fixed?: 'left' | 'right'
}

// 定义组件props
const props = defineProps({
  /**
   * 树形结构数据源
   * @type {TreeItem[]}
   */
  data: {
    type: Array as PropType<TreeItem[]>,
    required: true
  },
  /**
   * 表格列配置
   * @type {Column[]}
   */
  columns: {
    type: Array as PropType<Column[]>,
    required: true
  }
})

/**
 * 树形数据项接口
 * @property {string} Fid - 节点唯一标识
 * @property {string} FparentId - 父节点标识
 * @property {any} [key: string] - 其他动态属性
 * @property {TreeItem[]} [children] - 子节点数组
 */
interface TreeItem {
  Fid: string
  FparentId: string
  [key: string]: any
  children?: TreeItem[]
}

/**
 * 当前展开的节点ID数组
 * @type {Ref<string[]>}
 */
const expandedItems = ref<string[]>([])

/**
 * 递归扁平化树形数据
 * @param {TreeItem[]} data - 树形数据
 * @param {number} [level=0] - 当前层级
 * @param {string} [parentId] - 父节点ID
 * @returns {Array} 扁平化后的数据数组，包含level和parentId信息
 */
const flattenTree = (data: TreeItem[], level = 0, parentId?: string) => {
  return data.flatMap((item) => {
    const currentItem = { ...item, level, parentId }
    if (item.children) {
      return [currentItem, ...flattenTree(item.children, level + 1, item.Fid)]
    }
    return [currentItem]
  })
}

/**
 * 切换节点的展开/折叠状态
 * @param {string} Fid - 要切换的节点ID
 */
const toggleExpand = (Fid: string) => {
  const index = expandedItems.value.indexOf(Fid)
  if (index > -1) {
    expandedItems.value.splice(index, 1) // 如果已展开则折叠
  } else {
    expandedItems.value.push(Fid) // 如果已折叠则展开
  }
  // 视图更新后执行回调
  nextTick(() => {
    console.log('View updated')
  })
}

/**
 * 计算属性：获取当前可见的扁平化数据
 * 根据展开状态过滤数据，只显示展开的节点及其子节点
 * @returns {Array} 过滤后的扁平化数据
 */
const flattenedData = computed(() => {
  const allItems = flattenTree(props.data)
  return allItems.filter((item) => {
    if (item.level === 0) return true // 始终显示根节点
    let parentId = item.parentId
    // 检查所有父节点是否都已展开
    while (parentId !== undefined) {
      if (!expandedItems.value.includes(parentId)) {
        return false // 如果有父节点未展开，则隐藏该节点
      }
      const parentItem = allItems.find(i => i.Fid === parentId)
      parentId = parentItem?.parentId
    }
    return true
  })
})
</script>

<style scoped lang="scss">
.tree-table-container {
  overflow-x: auto;
  overflow-y: auto;
  width: 100%;
  position: relative;
  height: 600px; /* 设置固定高度 */
  max-height: 80vh; /* 最大高度为视口高度的80% */
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE 10+ */
  /* 确保sticky定位正常工作 */
  display: block;
}

/* 隐藏Webkit浏览器的滚动条 */
.tree-table-container::-webkit-scrollbar {
  display: none;
}

.tree-table {
  table-layout: fixed !important;
  border-collapse: collapse;
  font-family: Arial, sans-serif;
  min-width: 100%;
  width: auto;

}

.tree-table-container::-webkit-scrollbar {
  height: 8px;
}

.tree-table-container::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.tree-table-container::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 4px;
}

.tree-table-container::-webkit-scrollbar-thumb:hover {
  background: #555;
}

.tree-table th,
.tree-table td {
  min-width: 100rpx;
  width: auto;
  padding: 12rpx;
  text-align: left;
  border: 1px solid #e0e0e0;
  box-sizing: border-box;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tree-table th {
  background-color: #1976d2;
  color: white;
  font-weight: 500;
  position: sticky;
  top: 0;
  // z-index: 10; /* 提高z-index确保在最上层 */
  /* 告知浏览器某个元素即将发生 transform 属性的变化 */
  will-change: transform;
}

.tree-table .expand-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36rpx;
  height: 36rpx;
  background-color: #1976d2;
  color: white;
  border-radius: 50%;
  cursor: pointer;
  margin: 0 16rpx;
  user-select: none;
  transition: all 0.2s ease;

  &:hover {
    background-color: #1565c0;
  }
}

.tree-table .name-text {
  display: inline-block;
  margin-left: 16rpx;
  vertical-align: middle;
  max-width: 200rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tree-table .has-children>td {
  font-weight: bold;
}

.tree-table tr:hover {
  background-color: #f5f5f5;
}
</style>
